(() => {
    // 接口，是对象属性和方法的描述
    // 在面向对象的编程中，接口是一种规范的定义，它定义了行为和动作的规范。
    // 1.属性类接口
    interface FullName {
        firstName: string,
        lastName: string
    }
    function getFullName(fullName: FullName) {
        return fullName.firstName + '_' + fullName.lastName
    }
    let fullName = {
        age: 18,
        firstName: '巴黎',
        lastName: '世家'
    }
    // 间接赋值，ts没办法检查到该参数，是否符合接口，具体原因后续学习才清楚
    console.log(getFullName(fullName));
    // 直接赋值，由于age并没有在接口上定义，所以会报错
    // console.log(getFullName({
    //     age: 18,
    //     firstName: '巴黎',
    //     lastName: '世家'
    // }));

    //简单配置ajax（）
    interface Config {
        type: string,
        url: string,
        dataType: string
        data?: string
    }
    function Myajax(config: Config) {
        const xhr = new XMLHttpRequest()
        xhr.open(config.type, config.url, true)
        xhr.send(config.data)
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log('请求成功');
                if (config.dataType === 'json') {
                    console.log(JSON.parse(xhr.responseText));
                }
            }
        }
    }
    Myajax({
        type: 'get',
        url: 'http://a.itying.com/api/productlist',
        dataType: 'json',
        data: 'hhh'
    })


    // 2.函数类接口
    interface ConfigObj {
        key: string
        value: string
    }
    interface encrypt {
        (configObj: ConfigObj): string
    }
    const myMd5Cofig = {
        key: '属性类接口',
        value: '结合函数类接口'
    }
    const myFnConfig = {
        key: '001',
        value: '886',
        age: 18
    }
    let myMd5: encrypt = function (configObj: ConfigObj): string {
        return configObj.key + configObj.value
    }
    let myFn: encrypt = function (configObj: ConfigObj): string {
        return configObj.key + '_' + configObj.value
    }
    console.log(myMd5(myMd5Cofig));
    console.log(myFn(myFnConfig));


    // 3.可索引接口（数组，对象）
    // 数组
    interface UserArr {
        [index: number]: string
    }
    let userArr: UserArr = ['可索引', '接口']
    console.log(userArr);
    // 对象
    interface UserObj {
        [index: string]: string | number
    }
    let userObj: UserObj = {
        name: '李白',
        age: 18,
    }
    console.log(userObj);


    // 4.类类接口，有点类似抽象类
    interface Animal {
        name: string
        eat(floor: string): void
    }
    class Pig implements Animal {
        name: string
        constructor(name: string) {
            this.name = name
        }
        eat(floor: string): void {
            console.log(this.name + '在吃' + floor);

        }
    }
    class Cat implements Animal {
        name: string
        constructor(name: string) {
            this.name = name
        }
        eat(floor: string): void {
            console.log(this.name + '在吃' + floor);
        }
    }
    const pig = new Pig('小猪')
    const cat = new Cat('小花猫')
    pig.eat('大白菜')
    cat.eat('秋刀鱼')


    // 5.接口的扩展， 接口也可以继承
    interface Animal1 {
        name: string
        eat(): void
    }
    interface Person extends Animal1 {
        work(): void
    }
    class Person {
        codeing() {
            console.log('Person类中的方法');
        }
    }
    class Programmer extends Person implements Person {
        name: string
        constructor(name: string) {
            super()
        }
        eat(): void {
            console.log('Animal接口定义的吃的方法');
        };
        work(): void {
            console.log('Person接口定义的走的方法');
        }
    }
    const programmer = new Programmer('小王')
    programmer.eat()
    programmer.work()
    programmer.codeing()
})()